'use strict';
const path = require('path')
const cp = require('child_process')

const Package = require('@ting-cli-dev/package')
const log = require('@ting-cli-dev/log')

const SETTINGS = {
    init: '@ting-cli-dev/init' // 可用与test的库 @imooc-cli/init
}

const CACHE_DIR = 'dependencies'

// ting-cli-dev init demo  -tp /Users/leiting/Desktop/software/web-imoc/lt-cli-dev/commands/init  --debug -f

async function exec() {
    let targetPath = process.env.CLI_TARGET_PATH
    const homePath = process.env.CLI_HOME_PATH
    let storeDir = ''

    const cmdOptions = arguments[arguments.length - 2]
    const cmdObj = arguments[arguments.length - 1]

    console.log(cmdOptions);

    const cmdName = cmdObj.name();
    const packageName = SETTINGS[cmdName]
    const packageVersion = 'latest' // 调试的话，就选个小的版本

    if (!targetPath) {
        targetPath = path.resolve(homePath, CACHE_DIR) // 生成缓存路径
        storeDir = path.resolve(targetPath, 'node_modules')
    }

    const options = {
        targetPath,
        homePath,
        packageName,
        packageVersion,
        storeDir
    }
    log.verbose('package options: ', options)

    const pkg = new Package(options)

    if (cmdOptions.noUpdate && targetPath) {
        // 如果命令确定不更新，则不用判断 npm 包
    }else if (await pkg.exists()) { 
        // 更新 package
        console.log('更新 package');
        await pkg.update()
    } else {
        // 安装 package
        await pkg.install()
    }
   
    const rootFile = pkg.getRootFilePath()
    if (rootFile) {
        // 在当前进程中调用
        try {
            const args = Array.from(arguments);
            const cmd = args[args.length - 1]
            const o = Object.create(null)
            // 去掉参数中不必要的数据
            Object.keys(cmd).forEach(key => {
                if (cmd.hasOwnProperty(key) && 
                    !key.startsWith('_') &&
                    key !== 'parent') {
                    o[key] = cmd[key]
                }
            })
            args[args.length - 1] = o

            const code = `require('${rootFile}').call(null, ${JSON.stringify(args)})`
            
            const child = spawn('node', ['-e', code], {
                cwd: process.cwd(),
                stdio: 'inherit'
            })
            child.on('error', e => {
                log.error(e.message)
                process.exit(1)
            })
            child.on('exit', e => {
                log.verbose('命令执行成功：' + e)
                process.exit(e)
            })
            // 在 node 子进程中调用
            // require(rootFile).call(null, Array.from(arguments));
        } catch (error) {
            log.error(error.message)
        }
       
    }
}

// win 和 Macos 系统的兼容
// win 的话 cp.spawn('cmd', ['/c', 'node, '-e', code])
// Macos 的话 cp.spawn('node', ['-e', code])
function spawn(command, args, options) {
    const win32 = process.platform === 'win32';

    const cmd = win32 ? 'cmd' : command
    // '/c' 表示静默执行
    const cmdArags = win32 ? ['/c'].concat(command, args) : args
    return cp.spawn(cmd, cmdArags, options || {})
}


module.exports = exec;
